package org.example.wxdemo.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.example.wxdemo.config.WxConfig;
import org.example.wxdemo.model.WxAccessTokenResponse;
import org.example.wxdemo.model.WxTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
@Service
public class WxService {
    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
    private static final String TEMPLATE_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
    
    @Autowired
    private WxConfig wxConfig;
    
    @Autowired
    private RestTemplate restTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    private final AtomicReference<String> accessToken = new AtomicReference<>();
    
    @PostConstruct
    public void init() {
        refreshAccessToken();
    }
    
    /**
     * 定时刷新access_token，设置为每7000秒刷新一次（微信token有效期为7200秒）
     */
    @Scheduled(fixedRate = 7000000)
    public void refreshAccessToken() {
        try {
            String url = String.format(ACCESS_TOKEN_URL, wxConfig.getAppId(), wxConfig.getAppSecret());
            ResponseEntity<WxAccessTokenResponse> response = restTemplate.getForEntity(url, WxAccessTokenResponse.class);
            
            if (response.getBody() != null && response.getBody().getAccessToken() != null) {
                accessToken.set(response.getBody().getAccessToken());
                log.info("Successfully refreshed access token");
            } else {
                log.error("Failed to refresh access token: {}", response.getBody());
            }
        } catch (Exception e) {
            log.error("Error refreshing access token", e);
        }
    }
    
    /**
     * 获取当前的access_token
     */
    public String getAccessToken() {
        String token = accessToken.get();
        if (token == null) {
            refreshAccessToken();
            token = accessToken.get();
        }
        return token;
    }
    
    /**
     * 发送模板消息
     */
    public boolean sendTemplateMessage(WxTemplateMessage message) {
        try {
            String url = String.format(TEMPLATE_MESSAGE_URL, getAccessToken());
            
            // 创建一个符合微信API格式的Map
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("touser", message.getToUser());
            requestBody.put("template_id", message.getTemplateId());
            if (message.getUrl() != null) {
                requestBody.put("url", message.getUrl());
            }
            if (message.getMiniprogram() != null) {
                requestBody.put("miniprogram", message.getMiniprogram());
            }
            requestBody.put("data", message.getData());
            
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            
            // 创建HTTP实体
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
            
            // 打印实际发送的请求体
            log.info("Sending request to WeChat API: {}", objectMapper.writeValueAsString(requestBody));
            
            // 发送请求
            ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
            
            log.info("Template message sent. Response: {}", response.getBody());
            return response.getStatusCode().is2xxSuccessful();
        } catch (Exception e) {
            log.error("Error sending template message", e);
            return false;
        }
    }
} 